package com.coolwen.Realm;

import com.alibaba.fastjson.JSON;
import com.coolwen.entity.Resource;
import com.coolwen.entity.Role;
import com.coolwen.entity.User;
import com.coolwen.service.UserService;
import com.coolwen.util.EndecryptUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by user on 2016/6/4.
 */
public class MyShiroRealm extends AuthorizingRealm {

    private Logger logger = Logger.getLogger(getClass());

    @Autowired
    private UserService userService;

    //    用来判断授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User) principals.getPrimaryPrincipal();
        int uid = user.getId();
//        logger.info("授权用户:" + user.getId() + "," + user.getUsername());
        List<String> roles = userService.listRoleByUser(uid);
//        logger.info("授权用户roles:" + JSON.toJSON(roles));
        List<Resource> reses = userService.listUserRes(uid);
//        logger.info("授权用户reses:" + JSON.toJSON(reses));
        List<String> permissions = new ArrayList<String>();
        for (Resource r : reses) {
            permissions.add(r.getUrl());
        }
//        logger.info("授权用户permissions:" + JSON.toJSON(permissions));
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(new HashSet<String>(roles));
        info.setStringPermissions(new HashSet<String>(permissions));
//        logger.info("info:" + JSON.toJSON(info));
        return info;
    }

    //登录认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String username = String.valueOf(usernamePasswordToken.getUsername());
        //      String username = token.getPrincipal().toString();
        //       logger.info("登录用户名MyRelam:" + username);
        String password = new String(usernamePasswordToken.getPassword());
        User user = userService.loadByUserName(username);
        if (user == null) {
            // 抛出 帐号找不到异常
            throw new UnknownAccountException();
        }
        // 判断帐号是否锁定
        if (user.getStatus()) {
            // 抛出 帐号锁定异常
            throw new LockedAccountException("用户已经被锁定");
        }
        SimpleAuthenticationInfo info = null;
        //     logger.info("查找结果MyRelam" + user);
        if (user != null) {
            //           String password = ((char [])token.getCredentials()).toString();

            info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
            //          logger.info(" User用户名：" + user.getUsername() + " User的密码是：" + user.getPassword() + " User的salt是：" + user.getSalt());
            info.setCredentialsSalt(ByteSource.Util.bytes(username + user.getSalt()));

        }
//        logger.info("登录用户写入信息:" + JSON.toJSON(info));
        return info;
    }


    //清除认证
    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        User u = (User) principals.getPrimaryPrincipal();
        SimplePrincipalCollection sp = new SimplePrincipalCollection(u.getUsername(), getName());
        Cache c = this.getAuthenticationCache();
        Set<Object> keys = c.keys();
        for (Object o : keys) {
            logger.info("清除认证的缓存!" + o + "----------" + c.get(o) + "----------");
        }
        super.clearCachedAuthenticationInfo(sp);
        //   super.clearCachedAuthenticationInfo(principals);
    }


    //清除权限
    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {

        Cache c = this.getAuthorizationCache();
        Set<Object> keys = c.keys();
        for (Object o : keys) {
            logger.info("清除权限缓存!" + o + "-----" + c.get(o) + "----------");
        }
        super.clearCachedAuthorizationInfo(principals);
    }

}
